#!/bin/bash
#
# Copyright 2015-2017 Adrian DC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# === Git Show Helpers ===
alias gitshow='git show -M --name-status';
alias gitshf='git show -M --pretty=fuller';
function gitshl() { git show --oneline --name-only "${1}" | tail -n +2 | cut -c $((1+${2:-0}))-; }

# === Git Add Helpers ===
alias gitap='git add -p';
alias gitaa='git add . -Afv';
alias gitan='git add . -Afn';
alias gitanp='git config core.fileMode false; git add -p; git config --unset core.fileMode';
function gite() { fileedit "${1}"; echo -n ' Done ? [Enter] '; read -r; git add "${1}"; }

# === Git Branch Helpers ===
alias gitbd='git branch -D';
alias gitbv='git fetch ${gitreviewdefault} $(git rev-parse --abbrev-ref HEAD); git branch -vv';

# === Git Checkout Helpers ===
alias gitch='git checkout';

# === Git Cherry-Pick Helpers ===
alias gitcp='git cherry-pick';
alias gitcpc='git reset; git cherry-pick --continue';
function gitcpa() { for sha1 in "${@}"; do echo ''; echo "${sha1}"; git cherry-pick "${sha1}"; done; }
function gitcpf() { git fetch "${1}" "${2}"; git cherry-pick FETCH_HEAD; }
function gitcpr() { git show "${1}" --no-color | sed "s/${2}/${3}/g" | patch; }

# === Git Cherry-Pick Path ===
function gitfcp()
{
  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: gitfcp <path> [amount_of_commits] (Git cherry-pick from path)';
    echo '';
    return;
  fi;

  # Git cherry-pick from path
  git fetch "${1}";
  git cherry-pick --abort > /dev/null 2>&1;
  git cherry-pick "FETCH_HEAD~${2:-1}..FETCH_HEAD";
}

# === Git Commits Helpers ===
alias gitc='git commit $(gitgpgparam)';
alias gitce='git commit $(gitgpgparam) --allow-empty';
alias gitcs='git commit $(gitgpgparam) -s';
alias gitca='git commit $(gitgpgparam) --amend';
alias gitcae='git commit $(gitgpgparam) --amend --no-edit';
alias gitrevert='git revert $(gitgpgparam) --no-edit';

# === Git Commit Fixer ===
function gitfix()
{
  # Usage: gitfix (Fix git commit issues)

  # Fix git commit issues
  rm -fv .git/COMMIT_EDITMSG*;
  rm -fv .git/.COMMIT_EDITMSG.swp;
}

# === Git Author Commit ===
function gitcauthor()
{
  # Usage: gitcauthor (Apply own author to commit)

  # Variables
  local gitcommit;

  # Prepare git commit with gpg
  gitcommit="git commit $(gitgpgparam)";

  # Apply own author to commit
  ${gitcommit} --amend --no-edit --author="$(git config --global --get user.name) <$(git config --global --get user.email)>";
}

# === Git Marker Commit ===
function gitcamarker()
{
  # Usage: gitcamarker (Apply marker commit to author/committer)

  # Variables
  local gitcommit;

  # Prepare git commit with gpg
  gitcommit="git commit $(gitgpgparam)";

  # Apply marker commit to author/committer
  export GIT_COMMITTER_NAME="Marker Commit";
  export GIT_COMMITTER_EMAIL="marker.commit";
  ${gitcommit} --allow-empty --amend --no-edit --author="${GIT_COMMITTER_NAME} <${GIT_COMMITTER_EMAIL}>";
  unset GIT_COMMITTER_NAME;
  unset GIT_COMMITTER_EMAIL;
}

# === Git Commits Change-ID ===
function gitcid()
{
  # Usage: gitcid (Apply commit-msg hook to commit)

  # Variables
  local git_path='./.git';

  # Detect submodules
  if [ -f "${git_path}" ]; then
    git_path=$(cat "${git_path}");
    git_path=${git_path#*: };
  fi;

  # Copy commit-msg
  cp -fv "${ANDROID_DEVELOPMENT_SHELL_TOOLS_DIR}/addons/repo/commit-msg" "${git_path}/hooks/commit-msg";
  chmod u+x "${git_path}/hooks/commit-msg";

  # Update commit with Change-ID
  git commit --amend --no-edit;
  git commit --amend;
}

# === Git Commits Change-ID Upstream Download ===
function gitcidupstream()
{
  # Usage: gitcidupstream (Load commit-msg hook from upstream)

  # Variables
  local git_path='./.git';

  # Detect submodules
  if [ -f "${git_path}" ]; then
    git_path=$(cat "${git_path}");
    git_path=${git_path#*: };
  fi;

  # Fetch commit-msg file
  curl -Lo "${git_path}/hooks/commit-msg" http://review.lineageos.org/tools/hooks/commit-msg;
  cp -fv "${git_path}/hooks/commit-msg" "${ANDROID_DEVELOPMENT_SHELL_TOOLS_DIR}/addons/repo/commit-msg";
  chmod u+x "${git_path}/hooks/commit-msg";
}

# === Git Commit Stable
function gitcommitstable
{
  # Default variables
  local to_insert_default=RM-290;

  # Usage
  if [ -z "${1}" ]; then
    echo '';
    echo ' Usage: gitcommitstable <"commit_range"> <"to_insert (default RM-290)">';
    echo '';
    return;
  fi;

  # Variables
  local commit_range=${1};
  local to_insert=${2:-${to_insert_default}};

  # Single commits changes
  if [[ ! "${commit_range}" == *'..'* ]]; then
    commit_range=${commit_range}^..${commit_range};
  fi;

  # Pick and edit
  for commit_sha1 in $(git rev-list --reverse "${commit_range}"); do
    rm -f .git/COMMIT_EDITMSG;
    rm -f .git/.COMMIT_EDITMSG.swp;
    git cherry-pick "${commit_sha1}";
    sed -i -e "2,/^[^ ]*: .*/s/^\([^ ]*: .*\)/${to_insert}\n\n\1/" .git/COMMIT_EDITMSG;
    git commit --amend --edit --file=.git/COMMIT_EDITMSG;
    echo '';
  done;
}

# === Git Reset Helpers ===
alias gitrh='git reset FETCH_HEAD --hard';
alias githd='git reset HEAD --hard';
alias gitcl='git reset HEAD --hard; git stash -u; git am --abort';
alias gitro='git reset HEAD^ --hard';
alias gitsl='git reset HEAD^; gitap; gitcae';
alias gitrl='git revert HEAD -n; git commit -m "Revert"; git reset HEAD^; git add -p';
alias gitri='git reset HEAD^';
alias gitrt='git reset --hard';
